//
// Created by tianq on 25-5-3.
// Later we want one more type of shape as triangles and rectangles but we no longer Rectangles and Triangles.
//

#include <cmath>
#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class Shape {
public:
    virtual void draw() = 0;

    virtual ~Shape() = default;
};

class Triangle final : public Shape {
    float a{}, b{}, c{};

public:
    // equilateral triangle
    explicit Triangle(const float side = 1.0f) {
        cout << "Triangle::Triangle(side=" << side << ")" << endl;
        this->a = b = c = side;
    }

    explicit Triangle(const float a, const float b, const float c) {
        cout << "Triangle::Triangle(a=" << a << ", b=" << b << ", c=" << c << ")" << endl;
        this->a = a;
        this->b = b;
        this->c = c;
    }

    void draw() override {
        // calculate area using Heron's formula
        const float s = (a + b + c) / 2;
        const float area = sqrt(s * (s - a) * (s - b) * (s - c));
        cout << "Triangle::draw(), area=" << area << endl;
    }
};

class Rectangle final : public Shape {
    float w{}, h{};

public:
    // square
    explicit Rectangle(const float side = 1.0f) {
        cout << "Rectangle::Rectangle(side=" << side << ")" << endl;
        this->w = h = side;
    }

    explicit Rectangle(const float w, const float h) {
        cout << "Rectangle::Rectangle(w=" << w << ", h=" << h << ")" << endl;
        this->w = w;
        this->h = h;
    }

    void draw() override {
        cout << "Rectangle::draw(), area=" << w * h << endl;
    }
};

int main() {
    vector<unique_ptr<Shape>> shapes;

    shapes.push_back(make_unique<Triangle>(5.0f));
    shapes.push_back(make_unique<Rectangle>(3.0f));
    shapes.push_back(make_unique<Triangle>(3.0f, 4.0f, 5.0f));
    shapes.push_back(make_unique<Rectangle>(3.0f, 4.0f));

    for (const auto& shape : shapes) shape->draw();
}
